package main

import (
	"fmt"
)

//type A struct {
//	Name string
//	age  int
//}
//type B struct {
//	Name  string
//	Score float64
//}
//type C struct {
//	A
//	B
//	// Name string
//}
//
//type D struct {
//	a A // 有名结构体
//}

type Goods struct {
	Name  string
	Price float64
}

type Brand struct {
	Name    string
	Address string
}

type TV struct {
	Goods
	Brand
}

//type TV2 struct {
//	*Goods
//	*Brand
//}
//
//type Monster struct {
//	Name string
//	Age  int
//}
//
//type E struct {
//	Monster
//	int
//	n int
//}

func main() {
	//var c C
	//// 结构体嵌入两个(或多个)匿名结构体，如果两个匿名结构体有相同的字段和方法(同时结构体本身没有同名的字段和方法)，在访问时，就必须明确指定匿名结构体名字，否则编译报错。
	//// 如果 c 没有 Name 字段，而 A 和 B 有 Name, 这时就必须通过指定匿名结构体名字来区分。
	//// 所以 c.Name 就会编译错误， 这个规则对方法也是一样的！
	//c.A.Name = "tom"
	//fmt.Println("c")
	//
	//// 如果一个 struct 嵌套了一个有名结构体，这种模式就是组合，如果是组合关系，那么在访问组合的结构体的字段或方法时，必须带上结构体的名字。
	//var d D
	//d.a.Name = "jack"

	// 嵌套匿名结构体后，也可以在创建结构体变量(实例)时，直接指定各个匿名结构体字段的值
	tv := TV{Goods{"电视机001", 5000.99}, Brand{"海尔", "山东"}}

	// 演示访问 Goods 的 Name
	fmt.Println(tv.Goods.Name)
	fmt.Println(tv.Price)

	//tv2 := TV{
	//	Goods{
	//		Price: 5000.99,
	//		Name:  "电视机002",
	//	},
	//	Brand{
	//		Name:    "夏普",
	//		Address: "北京",
	//	},
	//}

	fmt.Println("tv", tv)
	//fmt.Println("tv2", tv2)
	//
	//tv3 := TV2{&Goods{"电视机003", 7000.99}, &Brand{"创维", "河南"}}
	//
	//tv4 := TV2{
	//	&Goods{
	//		Name:  "电视机004",
	//		Price: 9000.99,
	//	},
	//	&Brand{
	//		Name:    "长虹",
	//		Address: "四川",
	//	},
	//}
	//
	//fmt.Println("tv3", *tv3.Goods, *tv3.Brand)
	//fmt.Println("tv4", *tv4.Goods, *tv4.Brand)
	//
	//// 演示一下匿名字段是基本数据类型的使用
	//var e E
	//e.Name = "狐狸精"
	//e.Age = 300
	//e.int = 20
	//e.n = 40
	//fmt.Println("e=", e)
}
